package cxy.highConcurrency;

import java.io.IOException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class ThreadPoolDemo {

	public static void main(String[] args) throws IOException {
		//excutorsDemo();
		
		
		threadPoolExecutorDemo();

	}

	/**
	 * Executors 提供的很多方法默认使用的都是无界的 LinkedBlockingQueue，高负载情境下，无界队列很容易导致 OOM， 而 OOM
	 * 会导致所有请求都无法处理，这是致命问题。所以强烈建议使用有界队列。
	 */
	public static void excutorsDemo() {
		Executor threadPool = Executors.newFixedThreadPool(2);
		threadPool.execute(() -> {
			System.out.println("111");
		});

		threadPool.execute(() -> {
			System.out.println("222");
		});
	}

	public static void threadPoolExecutorDemo() throws IOException {
		ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
				3, //线程池保有的最小线程数
				10, //程池创建的最大线程数
				120, //如果一个线程空闲了keepAliveTime & unit这么久，而且线程池的线程数大于 corePoolSize ，那么这个空闲的线程就要被回收了。
				TimeUnit.SECONDS,
				new LinkedBlockingQueue<>(10),  //工作队列
				new CustomThreadFactory(), //threadFactory
				new ThreadPoolExecutor.AbortPolicy()); //任务拒绝策略
		
		 // 预启动所有核心线程
		threadPoolExecutor.prestartAllCoreThreads();

		System.out.println(threadPoolExecutor.getActiveCount());
		
		threadPoolExecutor.execute(() -> {
			System.out.println("111");
			System.out.println(Thread.currentThread().getName());
		});
		
		
		// 阻塞主线程
		System.in.read(); 
	}

	static class CustomThreadFactory implements ThreadFactory {
		private final AtomicInteger mThreadNum = new AtomicInteger(1);
		
		@Override
		public Thread newThread(Runnable r) {
			Thread t = new Thread(r, "my-thread-" + mThreadNum.getAndIncrement());
			return t;
		}
		
	}

}
